package com.laundry.shared.messaging

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import java.util.*
import java.util.concurrent.ConcurrentHashMap

/**
 * 消息同步管理器
 */
class MessageSyncManager {
    
    private val activeConnections = ConcurrentHashMap<String, ConnectionInfo>()
    private val messageQueue = ConcurrentHashMap<String, MutableList<PendingMessage>>()
    private val subscriptions = ConcurrentHashMap<String, MutableSet<String>>()
    
    /**
     * 建立连接
     */
    suspend fun connect(
        userId: String,
        platform: PlatformType,
        deviceId: String,
        connectionId: String
    ): Flow<ConnectionResult> = flow {
        try {
            val connectionInfo = ConnectionInfo(
                userId = userId,
                platform = platform,
                deviceId = deviceId,
                connectionId = connectionId,
                connectedAt = Date(),
                lastHeartbeat = Date(),
                isActive = true
            )
            
            // 保存连接信息
            activeConnections[connectionId] = connectionInfo
            
            // 发送离线消息
            sendPendingMessages(userId, connectionId)
            
            emit(ConnectionResult.Success(connectionInfo))
            
        } catch (e: Exception) {
            emit(ConnectionResult.Error("连接失败: ${e.message}"))
        }
    }
    
    /**
     * 断开连接
     */
    suspend fun disconnect(connectionId: String): Flow<Boolean> = flow {
        try {
            activeConnections[connectionId]?.let { connection ->
                activeConnections[connectionId] = connection.copy(
                    isActive = false,
                    disconnectedAt = Date()
                )
            }
            emit(true)
        } catch (e: Exception) {
            emit(false)
        }
    }
    
    /**
     * 发送消息
     */
    suspend fun sendMessage(message: CrossPlatformMessage): Flow<MessageResult> = flow {
        try {
            // 验证消息
            val validationResult = validateMessage(message)
            if (!validationResult.isValid) {
                emit(MessageResult.Error(validationResult.error))
                return@flow
            }
            
            // 获取目标用户的所有活跃连接
            val targetConnections = getActiveConnections(message.targetUserId)
            
            if (targetConnections.isEmpty()) {
                // 用户离线，保存到消息队列
                addToMessageQueue(message)
                emit(MessageResult.Queued(message.id))
            } else {
                // 用户在线，实时发送
                val deliveryResults = mutableListOf<DeliveryResult>()
                
                targetConnections.forEach { connection ->
                    val deliveryResult = deliverMessage(message, connection)
                    deliveryResults.add(deliveryResult)
                }
                
                // 保存消息记录
                saveMessageRecord(message, deliveryResults)
                
                emit(MessageResult.Delivered(message.id, deliveryResults))
            }
            
        } catch (e: Exception) {
            emit(MessageResult.Error("发送消息失败: ${e.message}"))
        }
    }
    
    /**
     * 广播消息
     */
    suspend fun broadcastMessage(
        message: BroadcastMessage,
        targetUsers: List<String>? = null
    ): Flow<BroadcastResult> = flow {
        try {
            val targets = targetUsers ?: getAllActiveUsers()
            val deliveryResults = mutableMapOf<String, List<DeliveryResult>>()
            
            targets.forEach { userId ->
                val userConnections = getActiveConnections(userId)
                val userDeliveries = mutableListOf<DeliveryResult>()
                
                if (userConnections.isNotEmpty()) {
                    userConnections.forEach { connection ->
                        val crossPlatformMessage = CrossPlatformMessage(
                            id = UUID.randomUUID().toString(),
                            type = message.type,
                            content = message.content,
                            senderId = message.senderId,
                            targetUserId = userId,
                            platform = connection.platform,
                            priority = message.priority,
                            createdAt = Date()
                        )
                        
                        val deliveryResult = deliverMessage(crossPlatformMessage, connection)
                        userDeliveries.add(deliveryResult)
                    }
                } else {
                    // 用户离线，添加到队列
                    val queuedMessage = CrossPlatformMessage(
                        id = UUID.randomUUID().toString(),
                        type = message.type,
                        content = message.content,
                        senderId = message.senderId,
                        targetUserId = userId,
                        platform = PlatformType.ALL,
                        priority = message.priority,
                        createdAt = Date()
                    )
                    addToMessageQueue(queuedMessage)
                }
                
                deliveryResults[userId] = userDeliveries
            }
            
            emit(BroadcastResult.Success(message.id, deliveryResults))
            
        } catch (e: Exception) {
            emit(BroadcastResult.Error("广播消息失败: ${e.message}"))
        }
    }
    
    /**
     * 订阅主题
     */
    suspend fun subscribe(userId: String, topic: String): Flow<Boolean> = flow {
        try {
            val userSubscriptions = subscriptions.getOrPut(userId) { mutableSetOf() }
            userSubscriptions.add(topic)
            emit(true)
        } catch (e: Exception) {
            emit(false)
        }
    }
    
    /**
     * 取消订阅
     */
    suspend fun unsubscribe(userId: String, topic: String): Flow<Boolean> = flow {
        try {
            subscriptions[userId]?.remove(topic)
            emit(true)
        } catch (e: Exception) {
            emit(false)
        }
    }
    
    /**
     * 发送主题消息
     */
    suspend fun publishToTopic(
        topic: String,
        message: TopicMessage
    ): Flow<PublishResult> = flow {
        try {
            // 获取订阅该主题的用户
            val subscribedUsers = getTopicSubscribers(topic)
            
            if (subscribedUsers.isEmpty()) {
                emit(PublishResult.NoSubscribers(topic))
                return@flow
            }
            
            // 创建广播消息
            val broadcastMessage = BroadcastMessage(
                id = UUID.randomUUID().toString(),
                type = MessageType.TOPIC_MESSAGE,
                content = message.content,
                senderId = message.senderId,
                topic = topic,
                priority = message.priority,
                createdAt = Date()
            )
            
            // 广播给订阅用户
            broadcastMessage(broadcastMessage, subscribedUsers).collect { result ->
                when (result) {
                    is BroadcastResult.Success -> {
                        emit(PublishResult.Success(topic, result.deliveryResults))
                    }
                    is BroadcastResult.Error -> {
                        emit(PublishResult.Error(result.error))
                    }
                }
            }
            
        } catch (e: Exception) {
            emit(PublishResult.Error("发布主题消息失败: ${e.message}"))
        }
    }
    
    /**
     * 同步消息状态
     */
    suspend fun syncMessageStatus(
        messageId: String,
        status: MessageStatus,
        platform: PlatformType,
        timestamp: Date = Date()
    ): Flow<Boolean> = flow {
        try {
            // 更新消息状态
            updateMessageStatus(messageId, status, platform, timestamp)
            
            // 通知其他平台同步状态
            notifyStatusChange(messageId, status, platform)
            
            emit(true)
        } catch (e: Exception) {
            emit(false)
        }
    }
    
    /**
     * 获取消息历史
     */
    suspend fun getMessageHistory(
        userId: String,
        platform: PlatformType? = null,
        limit: Int = 50,
        offset: Int = 0
    ): Flow<List<MessageRecord>> = flow {
        try {
            val messages = getMessagesFromDatabase(userId, platform, limit, offset)
            emit(messages)
        } catch (e: Exception) {
            emit(emptyList())
        }
    }
    
    /**
     * 心跳检测
     */
    suspend fun heartbeat(connectionId: String): Flow<Boolean> = flow {
        try {
            activeConnections[connectionId]?.let { connection ->
                activeConnections[connectionId] = connection.copy(
                    lastHeartbeat = Date()
                )
                emit(true)
            } ?: emit(false)
        } catch (e: Exception) {
            emit(false)
        }
    }
    
    /**
     * 获取连接状态
     */
    suspend fun getConnectionStatus(userId: String): Flow<List<ConnectionInfo>> = flow {
        try {
            val userConnections = activeConnections.values.filter { 
                it.userId == userId && it.isActive 
            }
            emit(userConnections.toList())
        } catch (e: Exception) {
            emit(emptyList())
        }
    }
    
    // 私有方法
    private fun validateMessage(message: CrossPlatformMessage): ValidationResult {
        if (message.content.isBlank()) {
            return ValidationResult(false, "消息内容不能为空")
        }
        if (message.targetUserId.isBlank()) {
            return ValidationResult(false, "目标用户ID不能为空")
        }
        return ValidationResult(true)
    }
    
    private fun getActiveConnections(userId: String): List<ConnectionInfo> {
        return activeConnections.values.filter { 
            it.userId == userId && it.isActive 
        }
    }
    
    private fun addToMessageQueue(message: CrossPlatformMessage) {
        val userQueue = messageQueue.getOrPut(message.targetUserId) { mutableListOf() }
        userQueue.add(PendingMessage(message, Date()))
    }
    
    private suspend fun sendPendingMessages(userId: String, connectionId: String) {
        messageQueue[userId]?.let { pendingMessages ->
            val connection = activeConnections[connectionId]
            if (connection != null) {
                pendingMessages.forEach { pendingMessage ->
                    deliverMessage(pendingMessage.message, connection)
                }
                // 清空已发送的消息
                messageQueue[userId]?.clear()
            }
        }
    }
    
    private suspend fun deliverMessage(
        message: CrossPlatformMessage,
        connection: ConnectionInfo
    ): DeliveryResult {
        return try {
            // 根据平台类型选择合适的推送方式
            when (connection.platform) {
                PlatformType.ANDROID -> deliverToAndroid(message, connection)
                PlatformType.IOS -> deliverToIOS(message, connection)
                PlatformType.WEB -> deliverToWeb(message, connection)
                PlatformType.WECHAT_MINI -> deliverToWechatMini(message, connection)
                PlatformType.ALIPAY_MINI -> deliverToAlipayMini(message, connection)
                PlatformType.H5 -> deliverToH5(message, connection)
                PlatformType.ALL -> deliverToAll(message, connection)
            }
        } catch (e: Exception) {
            DeliveryResult.Failed(connection.connectionId, e.message ?: "未知错误")
        }
    }
    
    private suspend fun deliverToAndroid(message: CrossPlatformMessage, connection: ConnectionInfo): DeliveryResult {
        // Android推送逻辑
        return DeliveryResult.Success(connection.connectionId, Date())
    }
    
    private suspend fun deliverToIOS(message: CrossPlatformMessage, connection: ConnectionInfo): DeliveryResult {
        // iOS推送逻辑
        return DeliveryResult.Success(connection.connectionId, Date())
    }
    
    private suspend fun deliverToWeb(message: CrossPlatformMessage, connection: ConnectionInfo): DeliveryResult {
        // Web WebSocket推送逻辑
        return DeliveryResult.Success(connection.connectionId, Date())
    }
    
    private suspend fun deliverToWechatMini(message: CrossPlatformMessage, connection: ConnectionInfo): DeliveryResult {
        // 微信小程序推送逻辑
        return DeliveryResult.Success(connection.connectionId, Date())
    }
    
    private suspend fun deliverToAlipayMini(message: CrossPlatformMessage, connection: ConnectionInfo): DeliveryResult {
        // 支付宝小程序推送逻辑
        return DeliveryResult.Success(connection.connectionId, Date())
    }
    
    private suspend fun deliverToH5(message: CrossPlatformMessage, connection: ConnectionInfo): DeliveryResult {
        // H5推送逻辑
        return DeliveryResult.Success(connection.connectionId, Date())
    }
    
    private suspend fun deliverToAll(message: CrossPlatformMessage, connection: ConnectionInfo): DeliveryResult {
        // 全平台推送逻辑
        return DeliveryResult.Success(connection.connectionId, Date())
    }
    
    private fun saveMessageRecord(message: CrossPlatformMessage, deliveryResults: List<DeliveryResult>) {
        // 保存消息记录到数据库
    }
    
    private fun getAllActiveUsers(): List<String> {
        return activeConnections.values.filter { it.isActive }.map { it.userId }.distinct()
    }
    
    private fun getTopicSubscribers(topic: String): List<String> {
        return subscriptions.filter { (_, topics) -> 
            topics.contains(topic) 
        }.keys.toList()
    }
    
    private fun updateMessageStatus(messageId: String, status: MessageStatus, platform: PlatformType, timestamp: Date) {
        // 更新数据库中的消息状态
    }
    
    private fun notifyStatusChange(messageId: String, status: MessageStatus, platform: PlatformType) {
        // 通知其他平台同步状态变更
    }
    
    private fun getMessagesFromDatabase(userId: String, platform: PlatformType?, limit: Int, offset: Int): List<MessageRecord> {
        // 从数据库获取消息历史
        return emptyList()
    }
}

data class ValidationResult(val isValid: Boolean, val error: String = "")
